package com.gitee.huanminabc.jcommon.multithreading;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @Description:
 * @Author huanmin
 * @Date 2024/6/5 下午4:30
 */
public interface LockReadWriteBase {

    void writeLock();
    boolean tryWriteLock();
    boolean tryWriteLock(long timeout, TimeUnit unit) throws InterruptedException;

    void readLock();
    boolean tryReadLock();
    boolean tryReadLock(long timeout, TimeUnit unit) throws InterruptedException;

    void unlock();



    default <T>  void writeLock(Runnable runnable) {
        writeLock();
        try {
            runnable.run();
        } finally {
            unlock();
        }
    }

    default <T>  T writeLock(Supplier<T> supplier) {
        writeLock();
        try {
            return supplier.get();
        } finally {
            unlock();
        }
    }

    default boolean tryWriteLock(Runnable runnable) {
        if (tryWriteLock()) {
            try {
                runnable.run();
                return true;
            } finally {
                unlock();
            }
        }
        return false;
    }

    default <T>  T tryWriteLock(T failResult, Supplier<T> supplier) {
        if (tryWriteLock()) {
            try {
                return supplier.get();
            } finally {
                unlock();
            }
        }
        return failResult;
    }

    //时间
    default  boolean tryWriteLock(long timeout, TimeUnit unit, Runnable runnable) throws InterruptedException {
        if (tryWriteLock( timeout, unit)) {
            try {
                runnable.run();
                return true;
            } finally {
                unlock();
            }
        }
        return false;
    }

    default <T> T tryWriteLock(long timeout, TimeUnit unit, T failResult, Supplier<T> supplier) throws InterruptedException {
        if (tryWriteLock( timeout, unit)) {
            try {
                return supplier.get();
            } finally {
                unlock();
            }
        }
        return failResult;
    }




    //读锁
    default void readLock( Runnable runnable) {
        readLock();
        try {
            runnable.run();
        } finally {
            unlock();
        }
    }

    //读锁
    default <T> T readLock( Supplier<T> supplier) {
        readLock();
        try {
            return supplier.get();
        } finally {
            unlock();
        }
    }
    default <T> T tryReadLock( T failResult, Supplier<T> supplier) {
        if (tryReadLock()) {
            try {
                return supplier.get();
            } finally {
                unlock();
            }
        }
        return failResult;
    }

    default boolean tryReadLock( Runnable runnable) {
        if (tryReadLock()) {
            try {
                runnable.run();
                return true;
            } finally {
                unlock();
            }
        }
        return false;
    }


    default <T> T tryReadLock( T failResult,long timeout, TimeUnit unit, Supplier<T> supplier) throws InterruptedException {
        if (tryReadLock( timeout, unit)) {
            try {
                return supplier.get();
            } finally {
                unlock();
            }
        }
        return failResult;
    }


    default boolean tryReadLock(long timeout, TimeUnit unit, Runnable runnable) throws InterruptedException {
        if (tryReadLock( timeout, unit)) {
            try {
                runnable.run();
                return true;
            } finally {
                unlock();
            }
        }
        return false;
    }

}
